<template>
  <component :is="componentName" />
</template>
<script setup lang="ts">
import { h, ref, type PropType, type VNode, useTemplateRef } from 'vue';
import type { TreeNode } from '../types/interface';

const props = defineProps({
  schema: {
    type: Object as PropType<TreeNode>,
    required: true,
  },
  modelValue: {
    type: Object as PropType<Record<string, unknown>>,
    default: '',
  },
});
const refObj: Record<string, any> = {};
const emit = defineEmits(['update:modelValue']);
const modelValue = ref(props.modelValue);
const renderItem = (item: TreeNode): VNode => {
  const attr = { ...item.attr };
  if (attr.model) {
    refObj[item.id] = useTemplateRef(item.id);
    attr.model = modelValue.value?.[attr.model as string] || {};
  }
  if (attr.valueField) {
    const fields = (attr.valueField as string).split('.');
    attr['modelValue'] = (modelValue.value?.data as Record<string, any>)?.[fields[1]] ?? '';
    attr['onMoute'];
    attr['onUpdate:modelValue'] = (newValue: string) => {
      if (!modelValue.value.data) {
        modelValue.value.data = {};
      }
      const data = modelValue.value.data as Record<string, any>;
      data[fields[1]] = newValue;
      emit('update:modelValue', modelValue.value);
    };
  }
  return h(
    item.name,
    {
      ...attr,
      ref: item.id,
    },
    () => [
      // 检查是否有子项来决定是否递归渲染
      item.children && item.children.length > 0 ? renderChildren(item.children) : attr.label,
    ],
  );
};
const renderChildren = (children: TreeNode[]) => {
  return children.map((child) => renderItem(child));
};

const componentName = {
  render: () => {
    return h('div', {}, [renderItem(props.schema)]);
  },
};

const getInstance = (id: string) => {
  const instance = refObj[id];
  return instance.value;
};

defineExpose({
  getInstance,
});
</script>
